﻿namespace OpenAdmin.Application.Services.System.Operation.Implements;

/// <summary>
/// 操作功能服务
/// </summary>
public class OperationService : ServiceBase, IOperationService, ITransientDependency
{
    private readonly IRepository<SysOperation, ApplicationDbContextLocator> _operationRepository;
    /// <summary>
    /// 
    /// </summary>
    /// <param name="operationRepository"></param>
    public OperationService(IRepository<SysOperation, ApplicationDbContextLocator> operationRepository)
    {
        _operationRepository = operationRepository;
    }

    /// <summary>
    /// 获取菜单操作功能
    /// </summary>
    /// <returns></returns>
    public async Task<List<OperationResponseDto>> GetOperationsByMenuId(int menuId)
    {
        var apiResourceRepository = _operationRepository.Change<SysApiResource, ApplicationDbContextLocator>();
        var operations = await (from o in _operationRepository.Entities
                                join a in apiResourceRepository.Entities on o.ApiResourceId equals a.Id into apiResource_join
                                from a in apiResource_join.DefaultIfEmpty()
                                where o.MenuId == menuId
                                select new OperationResponseDto
                                {
                                    Id = o.Id,
                                    Name = o.Name,
                                    Code = o.Code,
                                    ApiResourceId = o.ApiResourceId,
                                    ApiResourceName = a.Name
                                }).ToListAsync();
        return operations;
    }

    /// <summary>
    /// 添加菜单功能
    /// </summary>
    /// <param name="requestDto"></param>
    /// <returns></returns>
    public async Task AddOperation(AddOperationRequestDto requestDto)
    {
        var operation = _mapper.Map<SysOperation>(requestDto);
        operation.ParentId = 0;
        operation.CreateBy = UserIdentity.UserId;
        var operationEntry = await _operationRepository.Entities.AddAsync(operation);

        var permissionRepository = _operationRepository.Change<SysPermission, ApplicationDbContextLocator>();
        var permissionEntry = await permissionRepository.Entities.AddAsync(new SysPermission
        {
            Name = operation.Name,
            Type = SysConst.OPERATION,
            Remark = operation.Remark,
            CreateBy = UserIdentity.UserId,
        });

        var result = await _operationRepository.SaveChangesAsync();
        result.ThrowIf(p => p == 0, "添加失败");

        var permissionOperationRepository = _operationRepository.Change<SysPermissionOperation, ApplicationDbContextLocator>();
        await permissionOperationRepository.Entities.AddAsync(new SysPermissionOperation
        {
            OperationId = operationEntry.Entity.Id,
            PermissionId = permissionEntry.Entity.Id
        });

        result = await _operationRepository.SaveChangesAsync();
        result.ThrowIf(p => p == 0, "添加失败");
    }

    /// <summary>
    /// 编辑菜单功能
    /// </summary>
    /// <param name="requestDto"></param>
    /// <returns></returns>
    public async Task EditOperation(EditOperationRequestDto requestDto)
    {
        var operation = await _operationRepository.Entities.FindAsync(requestDto.Id);
        operation.ThrowIfNull("该功能不存在");

        operation.Name = requestDto.Name;
        operation.Code = requestDto.Code;
        operation.ApiResourceId = requestDto.ApiResourceId;
        operation.Sort = requestDto.Sort;
        operation.ModifyTime = DateTime.Now;
        operation.ModifyBy = UserIdentity.UserId;

        var uResult = await _operationRepository.SaveChangesAsync();
        uResult.ThrowIf(p => p == 0, "更新失败");
    }

    /// <summary>
    /// 删除
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public async Task DeleteOperation(int id)
    {
        var operation = await _operationRepository.Entities.FindAsync(id);
        operation.ThrowIfNull("该功能不存在");

        _operationRepository.Entities.Remove(operation);

        var permissionOperationRepository = _operationRepository.Change<SysPermissionOperation, ApplicationDbContextLocator>();
        var permisOperation = await permissionOperationRepository.Entities.SingleOrDefaultAsync(po => po.OperationId == operation.Id);
        if (permisOperation != null)
        {
            permissionOperationRepository.Entities.Remove(permisOperation);

            var permissionRepository = _operationRepository.Change<SysPermission, ApplicationDbContextLocator>();
            var permission = await permissionRepository.Entities.SingleOrDefaultAsync(p => p.Id == permisOperation.PermissionId);
            if (permission != null)
            {
                permissionRepository.Entities.Remove(permission);
            }
        }
        var dResult = await _operationRepository.SaveChangesAsync();
        dResult.ThrowIf(p => p == 0, "删除失败");
    }
}
